package com.earl.spider.util;
/**
 * @author 李振伟(Earl Li)
 * @projectName amazonspider
 * @description: ${description}
 * @date 2019/10/1613:10
 */

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.WebDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.*;
import java.nio.channels.FileChannel;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 实现文件的拷贝
 */
public class FileUtil {

    private static final Logger logger = LoggerFactory.getLogger(FileUtil.class);
    public static String config = FilePath.userHome + "\\config.txt";
    public static String paypal_config = FilePath.userHome + "\\paypal-config.txt";
    public static String payoneer_config = FilePath.userHome + "\\payoneer-config.txt";
    public static String aliexpress_config = FilePath.userHome + "\\aliexpress-config.txt";

    /**
     * 迭代删除文件夹
     *
     * @param dirPath 文件夹路径
     */
    public static void deleteDir(String dirPath) {
        File file = new File(dirPath);
        if (file.exists()) {
            if (file.isFile()) {
                file.delete();
            } else {
                File[] files = file.listFiles();
                if (files == null) {
                    file.delete();
                } else {
                    for (int i = 0; i < files.length; i++) {
                        deleteDir(files[i].getAbsolutePath());
                    }
                    file.delete();
                }
            }
        }
    }

    public static void deleteAllFile(String path) {
        deleteAllFile(path, "");
    }

    /**
     * 删除指定文件夹，指定后缀的文件 注意后缀需要大写
     *
     * @param path
     * @param suffix
     */
    public static void deleteAllFile(String path, String suffix) {
        try {
            File file = new File(path);
            if (!file.exists()) {
                file.mkdirs();
            }
            File[] files = file.listFiles();
            for (int i = 0; i < files.length; i++) {
                File tmp = files[i];
                if (tmp.exists() && tmp.isFile() && tmp.getName().toUpperCase().endsWith(suffix)) {
                    tmp.delete();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 更名pdf文件
     *
     * @param newName
     */
    public static void renamPdf(String newName, String filePath) {
        File[] files = new File(filePath).listFiles();
        for (File file : files) {
            if (file.isFile() && file.exists()) {
                file.toString().endsWith("pdf");
                file.renameTo(new File(filePath + newName + ".pdf"));
            }
        }

    }

    /**
     * 更名csv文件
     *
     * @param newName
     */
    public static void renameCsv(String newName, String filePath) {
        File[] files = new File(filePath).listFiles();
        for (File file : files) {
            if (file.isFile() && file.exists()) {
                file.toString().endsWith("csv");
                file.renameTo(new File(filePath + newName + ".csv"));
            }
        }

    }

    /**
     * 判断文件是否在被写入
     *
     * @return
     */
    public static boolean isFileWriting(String filePath) {
        File file = new File(filePath);
        if (file.exists() && file.isFile()) {
            if (file.renameTo(file)) {
                logger.error("文件未被操作");
                return false;
            } else {
                logger.error("文件正在下载");
                return true;
            }
        } else {
            return false;
        }
    }

    /**
     * 统计文件下包含字符串的为指定的文件个数
     *
     * @param path
     * @param str
     * @return
     */
    public static int fileNumContainStr(String path, String str) {
        int num = 0;
        File file = new File(path);
        File[] files = file.listFiles();
        for (int i = 0; i < files.length; i++) {
            File tmp = files[i];
            if (tmp.exists() && tmp.isFile()) {
                if (tmp.toString().contains(str)) {
                    num++;
                }
            }
        }
        return num;
    }

    /**
     * 清空文件夹下的所有内容
     *
     * @param path
     * @return
     */
    public static void deleteAll(String path) {
        File file = new File(path);
        //判断是否待删除目录是否存在
        if (!file.exists()) {
            file.mkdirs();
        }
        //取得当前目录下所有文件和文件夹
        String[] content = file.list();
        for (String name : content) {
            File temp = new File(path, name);
            //判断是否是目录
            if (temp.isDirectory()) {
                //递归调用，删除目录里的内容
                deleteDir(temp.getAbsolutePath());
                temp.delete();//删除空目录
            } else {
                //直接删除文件
                if (!temp.delete()) {
                    logger.info("Failed to delete " + name);
                }
            }
        }
    }

    public static void createUserData(String filePath) {
        deleteAll(FilePath.spiderChromPath);
        File dir = new File(filePath);
        // 一、检查放置文件的文件夹路径是否存在，不存在则创建
        if (!dir.exists()) {
            dir.mkdirs();// mkdirs创建多级目录
        }
        File checkFile = new File(filePath);
        FileWriter writer = null;
        try {
            // 二、检查目标文件是否存在，不存在则创建
            if (checkFile.exists()) {
                checkFile.delete();
            }
            checkFile.createNewFile();// 创建目标文件
            // 三、向目标文件中写入内容
            // FileWriter(File file, boolean append)，append为true时为追加模式，false或缺省则为覆盖模式
            writer = new FileWriter(checkFile, true);
            BufferedWriter bw = new BufferedWriter(writer);
            String bat = "xcopy " + FilePath.source + " " + FilePath.target + "  /c/e/r/y";
            bw.write(bat);
            bw.newLine();
            bw.flush();
            bw.close();
            callCmd(filePath);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != writer) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void callCmd(String locationCmd) {
        StringBuilder sb = new StringBuilder();
        try {
            Process child = Runtime.getRuntime().exec(locationCmd);
            InputStream in = child.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                sb.append(line + "\n");
            }
            in.close();
            try {
                child.waitFor();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            logger.info("callCmd execute finished");
        } catch (IOException e) {
            System.out.println(e);
        }
    }

    public static File copyFile(String source, String dest, String newFileName, String endWith) throws Exception {
        File file = new File(source);
        if (!file.exists()) return null;
        List<File> fileList = Arrays.asList(file.listFiles()).stream().filter(file1 -> file1.getName().endsWith(endWith)).collect(Collectors.toList());
        if (fileList.size() == 0) return null;
        File file1 = fileList.get(0);
        String oldFileName = file1.getName();
        String newFileName1;
        if (StringUtils.isEmpty(newFileName)) {
            newFileName1 = oldFileName;
        } else {
            newFileName1 = newFileName + oldFileName.substring(oldFileName.lastIndexOf("."));
        }
        File f1 = new File(source + oldFileName);
        File f2 = new File(dest + newFileName1);
        FileUtils.copyFile(f1, f2);
        logger.info("复制文件成功");
        return f2;
    }

    /**
     * Copy文件夹下的所有文件到新目录并更名
     *
     * @param source
     * @param dest
     * @param newFileName 为null则不更改文件名
     * @throws Exception
     */
    public static void copyFile(String source, String dest, String newFileName) throws Exception {
        try {
            File file = new File(source);
            if (!file.exists()) {
                throw new RuntimeException("文件夹目录不存在或不是文件");
            }
            File[] files = file.listFiles();
            for (File file1 : files) {
                if (!file1.isFile()) {
                    continue;
                }
                String oldFileName = file1.getName();
                String newFileName1;
                if (StringUtils.isEmpty(newFileName)) {
                    newFileName1 = oldFileName;
                } else {
                    newFileName1 = newFileName + oldFileName.substring(oldFileName.lastIndexOf("."));
                }
                File f1 = new File(source + oldFileName);
                File f2 = new File(dest + newFileName1);
                FileUtils.copyFile(f1, f2);
            }
            logger.info("复制文件成功");
        } catch (IOException e) {
            logger.info("复制文件失败");
            throw e;
        }
        FileUtil.deleteAll(source);
    }

    /**
     * 写txt
     *
     * @param fileName
     * @param data
     */
    public static void writeTxt(String fileName, String data) {
        try {
            File writename = new File(fileName);
            // 创建新文件
            if (!writename.exists()) writename.createNewFile();
            BufferedWriter out = new BufferedWriter(new FileWriter(writename));
            // \r\n即为换行
            out.write(data);
            // 把缓存区内容压入文件
            out.flush();
            // 最后记得关闭文件
            out.close();
            logger.info("写TXT文件成功");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("写TXT文件失败");
        }
    }

    /**
     * 写txt
     *
     * @param fileName
     * @param data
     */
    public static void writeTxtAsUtf8(String fileName, String data) {
        try {
            File file = new File(fileName);
            // 创建新文件
            if (!file.exists()) file.createNewFile();
            BufferedWriter writer;
            FileOutputStream writerStream = new FileOutputStream(file);
            writer = new BufferedWriter(new OutputStreamWriter(writerStream, "UTF-8"));
            writer.write(data);
            // \r\n即为换行
            // 把缓存区内容压入文件
            writer.flush();
            // 最后记得关闭文件
            writer.close();
            logger.info("写TXT文件成功");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("写TXT文件失败");
        }
    }

    /**
     * 判断文件下是否有文件大小
     *
     * @param path 文件夹路径
     * @param end  后缀名
     * @return
     */
    public static long fileSizeNum(String path, String end) {
        long size = 0;
        File file = new File(path);
        File[] files = file.listFiles();
        for (int i = 0; i < files.length; i++) {
            File tmp = files[i];
            if (tmp.exists() && tmp.isFile()) {
                if (tmp.toString().endsWith(end)) {
                    FileChannel fc = null;
                    FileInputStream fis = null;
                    try {
                        fis = new FileInputStream(tmp);
                        fc = fis.getChannel();
                        size = fc.size();

                    } catch (FileNotFoundException e) {
                        System.out.println(e.getMessage());
                    } catch (IOException e) {
                        System.out.println(e.getMessage());
                    } finally {
                        if (null != fc) {
                            try {
                                fis.close();
                                fc.close();
                            } catch (IOException e) {
                                System.out.println(e.getMessage());
                            }
                        }
                    }
                }
            } else {
                size = 0;
                logger.info("file doesn't exist or is not a file");
            }
        }
        return size;
    }

    public static List<File> getFileList(String path, String fileMatch) {
        return Arrays.asList(new File(path).listFiles()).stream().filter(file -> file.getName().matches(fileMatch)).collect(Collectors.toList());
    }

    public static String readFile(String filePath) {
        if (!new File(filePath).exists()) return "";
        StringBuffer sb = new StringBuffer();
        FileReader fileReader = null;
        BufferedReader reader = null;
        try {
            fileReader = new FileReader(filePath);
            reader = new BufferedReader(fileReader);
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fileReader != null) {
                    fileReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

    /**
     * 下载
     *
     * @throws Exception
     */
    public static void downloading(String chromeDownPath, WebDriver driver) throws Exception {
        String currentHandle = driver.getWindowHandle();
        File tmpFile = new File(chromeDownPath);
        File[] files = tmpFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            File tmp = files[i];
            if (tmp.exists() && tmp.isFile()) {
                if (tmp.toString().endsWith(".crdownload") || tmp.toString().endsWith(".part") || tmp.toString().endsWith(".tmp")) {
                    while (FileUtil.isFileWriting(tmp.getAbsolutePath())) {
                        Thread.sleep(2 * 1000);
                        logger.info("文件正在下载中...");
                    }
                }
            }
        }
        while (driver.getWindowHandles().size() > 1) {
            System.out.println(driver.getWindowHandles().size());
            Thread.sleep(1 * 1000);
            Set<String> windowHandles = driver.getWindowHandles();
            for (String string : windowHandles) {
                if (!string.equals(currentHandle)) {
                    driver.switchTo().window(string);
                    driver.close();
                }
            }
        }
        driver.switchTo().window(currentHandle);
    }
}